package sweproject;
import utility.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import utility.Timer;
import button.*;
import java.util.ArrayList;
import java.util.List;

public class GamePanel extends JPanel{
	private static GamePanel gp = null;
	
	public int gameWidth;
	public int gameHeight;
	public boolean gameOver;
	public boolean pause;
	
	private Thread paintThread = null;
	private Image offScreenImage = null;
	private Graphics2D elementPainter2D;
	private boolean isRunning;
	//
	private List<MyButton> buttons;
	private Timer t;
	//
	
	private GamePanel(){
		gameWidth = 800;
		gameHeight = 600;
		gameOver = false;
		pause = false;
		buttons = new ArrayList<MyButton>();
		t = new Timer(gameWidth, gameHeight);
		this.setFocusable(true);
		this.requestFocus();
		this.addMouseListener(new MyListener());
	}
	
	public void addButton(MyButton b){
		buttons.add(b);
	}
	
	private void startGame(){
		if(paintThread == null){
			paintThread = new Thread(new PaintThread());
		}
		paintThread.start();
	}
	public static GamePanel getGamePanel(){
		if(gp == null){
			gp = new GamePanel();
		}
		return gp;
	}
	
	public void addNotify(){
		super.addNotify();
		startGame();
	}
	
	private void gameUpdate(){
		if(!gameOver){
			if(t.isPause()){
				for(MyButton b : buttons){
					b.setActiveFalse();
				}
			}
		}
	}
	
	public void stopGame(){
		isRunning = false;
	}
	public void pause(){
		t.stop();
		pause = true;
		for(MyButton b : buttons){
			b.setActiveFalse();
		}
	}
	public void resume(){
		t.resume();
		pause = false;
		for(MyButton b : buttons){
			b.setActiveTrue();
		}
	}
	private void gameRender(){
		if(offScreenImage == null){
			offScreenImage = gp.createImage(gameWidth, gameHeight);
			if(offScreenImage == null){
System.out.println("Cannot create Image");
				return;
			}else{
				elementPainter2D = (Graphics2D)offScreenImage.getGraphics();
				Utility.programGraphics(elementPainter2D);
			}
		}
		Color c = elementPainter2D.getColor();
		elementPainter2D.setColor(Color.WHITE);
		elementPainter2D.fillRect(0, 0, gameWidth, gameHeight);
		for(MyButton b: buttons){
			b.draw(elementPainter2D);
		}
		t.draw(elementPainter2D);
		if(pause){
			elementPainter2D.setColor(new Color(220, 220, 220, 200));
			elementPainter2D.fillRect(0, 0, gameWidth, gameHeight);
		}
		elementPainter2D.setColor(c);
	}
	private void paintScreen(){
		Graphics2D g = null;
		try{
			g = (Graphics2D)gp.getGraphics();
			if(offScreenImage != null && g != null){
				g.drawImage(offScreenImage, 0, 0, null);
			}
			g.dispose();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	private class PaintThread implements Runnable{
		public void run(){
			isRunning = true;

			while(isRunning){
				gameUpdate();
				gameRender();
				paintScreen();
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.exit(0);
		}
	}
	
	private class MyListener extends MouseAdapter{
		public void mousePressed(MouseEvent e){
			for(MyButton b : buttons){
				b.pressed(e);
			}
		}
		public void mouseReleased(MouseEvent e){
			for(MyButton b : buttons){
				b.released(e);
			}
		}
	}
}
